//lead in a straight line (doesn't track circlestrafe well)

function A_BrakFireShot(mo, var1)
	local x
	local y
	local z
	local dx
	local dy
	local dz
	local dang
	local diststeps
	local shot = mobjinfo[var1]
	if not (mo.target) then return end
	diststeps = FixedDiv(R_PointToDist2(mo.x, mo.y, mo.target.x, mo.target.y), shot.speed)
	dx = mo.target.x + FixedMul(mo.target.momx, diststeps)
	dy = mo.target.y + FixedMul(mo.target.momy, diststeps)
	//dz = mo.target.z + FixedMul(mo.target.momz, diststeps)
	dang = R_PointToAngle2(mo.x, mo.y, dx, dy)
	mo.angle = dang
	x = mo.x+P_ReturnThrustX(mo, mo.angle, 64*mo.scale)+P_ReturnThrustX(mo, mo.angle+ANGLE_270, 64*mo.scale)
	y = mo.y+P_ReturnThrustY(mo, mo.angle, 64*mo.scale)+P_ReturnThrustY(mo, mo.angle+ANGLE_270, 64*mo.scale)
	if (mo.eflags & MFE_VERTICALFLIP) then
		z = mo.z + mo.height - (144*mo.scale)
	else
		z = mo.z + (144*mo.scale)
	end
	
	P_SpawnPointMissile(mo, dx, dy, mo.target.z, var1, x, y, z)
	
	if (not(mo.flags & MF_BOSS)) then
		if ultimatemode then
			mo.reactiontime = mo.info.reactiontime*TICRATE
		else
			mo.reactiontime = mo.info.reactiontime*TICRATE*2
		end
	end
end

function A_BrakFireShotOld(mo, var1)
	local x
	local y
	local z
	local shot = mobjinfo[var1]
	if not (mo.target) then return end
	A_FaceTarget(mo)
	x = mo.x+P_ReturnThrustX(mo, mo.angle, 64*mo.scale)+P_ReturnThrustX(mo, mo.angle+ANGLE_270, 64*mo.scale)
	y = mo.y+P_ReturnThrustY(mo, mo.angle, 64*mo.scale)+P_ReturnThrustY(mo, mo.angle+ANGLE_270, 64*mo.scale)
	if (mo.eflags & MFE_VERTICALFLIP) then
		z = mo.z + mo.height - (144*mo.scale)
	else
		z = mo.z + (144*mo.scale)
	end
	
	P_SpawnXYZMissile(mo, mo.target, var1, x, y, z)
	
	if (not(mo.flags & MF_BOSS)) then
		if ultimatemode then
			mo.reactiontime = mo.info.reactiontime*TICRATE
		else
			mo.reactiontime = mo.info.reactiontime*TICRATE*2
		end
	end
end

function A_BrakFireShotTriple(mo, var1)
	local x
	local y
	local z
	local dx
	local dy
	local dz
	local dang
	local diststeps
	local shot = mobjinfo[var1]
	if not (mo.target) then return end
	diststeps = FixedDiv(R_PointToDist2(mo.x, mo.y, mo.target.x, mo.target.y), shot.speed)
	dx = mo.target.x + FixedMul(mo.target.momx, diststeps)
	dy = mo.target.y + FixedMul(mo.target.momy, diststeps)
	//dz = mo.target.z + FixedMul(mo.target.momz, diststeps)
	dang = R_PointToAngle2(mo.x, mo.y, dx, dy)
	mo.angle = dang
	x = mo.x+P_ReturnThrustX(mo, mo.angle, 64*mo.scale)+P_ReturnThrustX(mo, mo.angle+ANGLE_270, 64*mo.scale)
	y = mo.y+P_ReturnThrustY(mo, mo.angle, 64*mo.scale)+P_ReturnThrustY(mo, mo.angle+ANGLE_270, 64*mo.scale)
	if (mo.eflags & MFE_VERTICALFLIP) then
		z = mo.z + mo.height - (144*mo.scale)
	else
		z = mo.z + (144*mo.scale)
	end
	
	P_SpawnPointMissile(mo, dx, dy, mo.target.z, var1, x, y, z)
	//P_SpawnPointMissile(mo, dx + 32*cos(FixedAngle(leveltime*10*FU)), dy + 32*sin(FixedAngle(leveltime*10*FU)), mo.target.z, var1, x, y, z)
	//P_SpawnPointMissile(mo, dx - 32*cos(FixedAngle(leveltime*10*FU)), dy - 32*sin(FixedAngle(leveltime*10*FU)), mo.target.z, var1, x, y, z)
	//P_SpawnPointMissile(mo, dx + P_RandomRange(-16*FU, 16*FU), dy + P_RandomRange(-16*FU, 16*FU), mo.target.z, var1, x, y, z+P_RandomRange(-32*FU, 32*FU))
	//P_SpawnPointMissile(mo, dx + P_RandomRange(-16*FU, 16*FU), dy + P_RandomRange(-16*FU, 16*FU), mo.target.z, var1, x, y, z+P_RandomRange(-32*FU, 32*FU))
	
	if (not(mo.flags & MF_BOSS)) then
		if ultimatemode then
			mo.reactiontime = mo.info.reactiontime*TICRATE
		else
			mo.reactiontime = mo.info.reactiontime*TICRATE*2
		end
	end
end

//tracks in a circle (hard counters circle strafe)

/*function A_BrakFireShot(mo, var1)
	local x
	local y
	local z
	local dx
	local dy
	local dz
	local dang
	local diststeps
	local angvelocity
	local shot = mobjinfo[var1]
	if not (mo.target) then return end
	diststeps = FixedDiv(R_PointToDist2(mo.x, mo.y, mo.target.x, mo.target.y), shot.speed)
	angvelocity = FixedDiv(FixedHypot(mo.target.momx, mo.target.momy), R_PointToDist2(mo.x, mo.y, mo.target.x, mo.target.y))
	dx = mo.x + FixedMul(R_PointToDist2(mo.x, mo.y, mo.target.x, mo.target.y), cos(FixedAngle(AngleFixed(R_PointToAngle2(mo.x, mo.y, mo.target.x, mo.target.y)) + FixedMul(angvelocity, diststeps))))
	dy = mo.y + FixedMul(R_PointToDist2(mo.x, mo.y, mo.target.x, mo.target.y), sin(FixedAngle(AngleFixed(R_PointToAngle2(mo.x, mo.y, mo.target.x, mo.target.y)) + FixedMul(angvelocity, diststeps))))
	//dz = mo.target.z + FixedMul(mo.target.momz, diststeps)
	dang = R_PointToAngle2(mo.x, mo.y, dx, dy)
	mo.angle = dang
	x = mo.x+P_ReturnThrustX(mo, mo.angle, 64*mo.scale)+P_ReturnThrustX(mo, mo.angle+ANGLE_270, 64*mo.scale)
	y = mo.y+P_ReturnThrustY(mo, mo.angle, 64*mo.scale)+P_ReturnThrustY(mo, mo.angle+ANGLE_270, 64*mo.scale)
	if (mo.eflags & MFE_VERTICALFLIP) then
		z = mo.z + mo.height - (144*mo.scale)
	else
		z = mo.z + (144*mo.scale)
	end
	
	P_SpawnPointMissile(mo, dx, dy, mo.target.z, var1, x, y, z)
	
	if (not(mo.flags & MF_BOSS)) then
		if ultimatemode then
			mo.reactiontime = mo.info.reactiontime*TICRATE
		else
			mo.reactiontime = mo.info.reactiontime*TICRATE*2
		end
	end
end*/

states[S_CYBRAKDEMONMISSILE_EXPLODE1] = {
	sprite = RCKT,
	frame = B,
	action = A_RingExplode,
	tics = 8,
	nextstate = S_CYBRAKDEMONMISSILE_EXPLODE2
}

freeslot("S_CYBRAKDEMON_MISSILE_ATTACK7", "S_CYBRAKDEMON_MISSILE_ATTACK8", "S_CYBRAKDEMON_MISSILE_ATTACK9", "S_CYBRAKDEMON_MISSILE_ATTACK10", "S_CYBRAKDEMON_MISSILE_ATTACK11", "S_CYBRAKDEMON_MISSILE_ATTACK12")

states[S_CYBRAKDEMON_MISSILE_ATTACK7] = {
	sprite = states[S_CYBRAKDEMON_MISSILE_ATTACK1].sprite,
	frame = states[S_CYBRAKDEMON_MISSILE_ATTACK1].frame,
	action = A_FaceTarget,
	tics = 3,
	nextstate = S_CYBRAKDEMON_MISSILE_ATTACK8
}

states[S_CYBRAKDEMON_MISSILE_ATTACK8] = {
	sprite = states[S_CYBRAKDEMON_MISSILE_ATTACK2].sprite,
	frame = states[S_CYBRAKDEMON_MISSILE_ATTACK2].frame,
	action = A_BrakFireShotOld,
	tics = 6,
	var1 = MT_CYBRAKDEMON_MISSILE,
	var2 = 128,
	nextstate = S_CYBRAKDEMON_MISSILE_ATTACK9
}

states[S_CYBRAKDEMON_MISSILE_ATTACK9] = {
	sprite = states[S_CYBRAKDEMON_MISSILE_ATTACK1].sprite,
	frame = states[S_CYBRAKDEMON_MISSILE_ATTACK1].frame,
	action = A_FaceTarget,
	tics = 3,
	nextstate = S_CYBRAKDEMON_MISSILE_ATTACK10
}

states[S_CYBRAKDEMON_MISSILE_ATTACK10] = {
	sprite = states[S_CYBRAKDEMON_MISSILE_ATTACK2].sprite,
	frame = states[S_CYBRAKDEMON_MISSILE_ATTACK2].frame,
	action = A_BrakFireShot,
	tics = 6,
	var1 = MT_CYBRAKDEMON_MISSILE,
	var2 = 128,
	nextstate = S_CYBRAKDEMON_MISSILE_ATTACK11
}

states[S_CYBRAKDEMON_MISSILE_ATTACK11] = {
	sprite = states[S_CYBRAKDEMON_MISSILE_ATTACK1].sprite,
	frame = states[S_CYBRAKDEMON_MISSILE_ATTACK1].frame,
	action = A_FaceTarget,
	tics = 3,
	nextstate = S_CYBRAKDEMON_MISSILE_ATTACK12
}

states[S_CYBRAKDEMON_MISSILE_ATTACK12] = {
	sprite = states[S_CYBRAKDEMON_MISSILE_ATTACK2].sprite,
	frame = states[S_CYBRAKDEMON_MISSILE_ATTACK2].frame,
	action = A_BrakFireShotOld,
	tics = 6,
	var1 = MT_CYBRAKDEMON_MISSILE,
	var2 = 128,
	nextstate = S_CYBRAKDEMON_FINISH_ATTACK1
}

states[S_CYBRAKDEMON_WALK1].var1 = 2
states[S_CYBRAKDEMON_WALK2].var1 = 2
states[S_CYBRAKDEMON_WALK3].var1 = 2
states[S_CYBRAKDEMON_WALK4].var1 = 2
states[S_CYBRAKDEMON_WALK5].var1 = 2
states[S_CYBRAKDEMON_WALK6].var1 = 2
states[S_CYBRAKDEMON_FLAME_ATTACK3].action = A_BrakFireShotTriple
states[S_CYBRAKDEMON_MISSILE_ATTACK1].tics = 3
states[S_CYBRAKDEMON_MISSILE_ATTACK2].tics = 6
states[S_CYBRAKDEMON_MISSILE_ATTACK3].tics = 3
states[S_CYBRAKDEMON_MISSILE_ATTACK4].tics = 6
states[S_CYBRAKDEMON_MISSILE_ATTACK4].action = A_BrakFireShotOld
states[S_CYBRAKDEMON_MISSILE_ATTACK5].tics = 3
states[S_CYBRAKDEMON_MISSILE_ATTACK6].tics = 6
states[S_CYBRAKDEMON_MISSILE_ATTACK6].nextstate = S_CYBRAKDEMON_MISSILE_ATTACK7

mobjinfo[MT_CYBRAKDEMON_MISSILE].painchance = 384*FU
mobjinfo[MT_CYBRAKDEMON_FLAMESHOT].speed = 35*FU
mobjinfo[MT_CYBRAKDEMON].reactiontime = 5

RFW.DAMAGETABLE[MT_CYBRAKDEMON_MISSILE] = {40, 80}
RFW.DAMAGETABLE[MT_CYBRAKDEMON] = {100, 100}

local function BrakSpread(mo, ldamage, damage, hspread, vspread, range, amount, pierce, tracer)
	for i = 1, amount do
		local nhspread = FixedAngle(P_RandomRange(-hspread, hspread))
		local nvspread = FixedAngle(P_RandomRange(-vspread, vspread))
		mo.angle = R_PointToAngle2(mo.x, mo.y, mo.shotguntarget.x, mo.shotguntarget.y)
		local dx = mo.x - mo.shotguntarget.x
		local dy = mo.y - mo.shotguntarget.y
		local dz = mo.z+mo.height/2 - mo.shotguntarget.z
		local dxy = P_AproxDistance(dx, dy)
		local targetlist = P_AngleRaycast{x = mo.x, y = mo.y, z = mo.z+mo.height/2, ang = mo.angle+nhspread, zang = -R_PointToAngle2(0, 0, dxy, dz)+nvspread, distance = range, steps = FixedInt(range)/16, tclip = (not pierce), lclip = true, ignore = mo, callback = (tracer) and P_SpawnMobj or nil, arg = tracer, callback2 = P_SpawnMobj, larg = MT_SMOKE}
		if not next(targetlist) then continue end
		local target = targetlist[1][4]
		if target.type == MT_PLAYER then
			Playerdamage(target, mo, mo, P_RandomRange(ldamage, damage) or 5, 0, true)
			continue
		else
			for i = 1, P_RandomRange(1, 3) do
				RFW.SparkCoordinate(target, targetlist[1][1], targetlist[1][2], targetlist[1][3])
			end
			P_DamageMobj(target, mo, mo, P_RandomRange(ldamage, damage) or 5, 0)
			continue
		end
	end
end

freeslot("sfx_ssgfir")

addHook("MobjThinker", function(mo)
	if mo.state == S_CYBRAKDEMON_MISSILE_ATTACK1 then
		S_StartSound(mo, sfx_gbeep)
		for i = 1,20 do //do this part 10 times
			local ghost = P_SpawnGhostMobj(mo)
			ghost.color = SKINCOLOR_COBALT //random color
			ghost.colorized = true
			ghost.momx = P_RandomRange(-15, 15)*P_RandomFixed()*(4-mo.tics)
			ghost.momy = P_RandomRange(-15, 15)*P_RandomFixed()*(4-mo.tics)
			ghost.momz = P_RandomRange(-15, 15)*P_RandomFixed()*(4-mo.tics)
		end
	end
	if mo.state == S_CYBRAKDEMON_FLAME_ATTACK1 then
		S_StartSound(mo, sfx_deton)
		for i = 1,20 do //do this part 10 times
			local ghost = P_SpawnGhostMobj(mo)
			ghost.color = SKINCOLOR_FLAME //random color
			ghost.colorized = true
			ghost.momx = P_RandomRange(-15, 15)*P_RandomFixed()*(4-mo.tics)
			ghost.momy = P_RandomRange(-15, 15)*P_RandomFixed()*(4-mo.tics)
			ghost.momz = P_RandomRange(-15, 15)*P_RandomFixed()*(4-mo.tics)
		end
	end
	/*if mo.shotguncooldown == nil then
		mo.shotguncooldown = 0
	end
	searchBlockmap("objects", function(brak, fmo)
		if not (fmo and fmo.valid) then return end //if we don't have an object keep checking
		if brak.target ~= fmo and fmo.type ~= MT_PLAYER then return end //if our object isn't a player or the one we're targeting then keep checking (infighting allows brak to target non-players which is why the second condition is here)
		if not (fmo.flags & MF_SHOOTABLE) then return end //if bullets wont work then tell jon to run
		if abs((brak.z+brak.height/2)-(fmo.z+fmo.height/2)) > 192*FU then return end
		if brak.shotguncooldown then return end //we're firing/on cooldown
		brak.shotguntarget = fmo
		brak.shotguncooldown = 15
		return true
	end, mo, mo.x-192*FU, mo.x+192*FU, mo.y-192*FU, mo.y+192*FU)
	if mo.shotguncooldown > 0 then
		if mo.shotguntarget == nil then
			mo.shotguncooldown = min($, 3)
		else
			if mo.shotguncooldown > 9 and mo.shotguncooldown%2 then
				S_StartSound(mo, sfx_ssgfir)
				BrakSpread(mo, 5, 15, 5*FU + FU/2, 3*FU + FU/2, 4096*FU, 20, false, MT_TRACER)
				//mo.frame = 6
			end
			mo.shotguncooldown = max($-1, 0)
			if mo.shotguncooldown == 0 then
				mo.shotguntarget = nil
			end
		end
	end*/
end, MT_CYBRAKDEMON)

freeslot("MT_FAKEBRAK")
freeslot("S_GLUP_SHITTO")

mobjinfo[MT_FAKEBRAK] = {
	//$Category "Rampage Scripting"
	doomednum = -1,
	spawnstate = S_GLUP_SHITTO,
	spawnhealth = 999999999,
	seestate = S_NULL,
	seesound = sfx_null,
	reactiontime = 1,
	attacksound = sfx_null,
	painstate = S_NULL,
	painchance = 8192,
	painsound = sfx_null,
	meleestate = S_NULL,
	missilestate = S_NULL,
	deathstate = S_NULL,
	xdeathstate = S_NULL,
	deathsound = sfx_wpnup,
	speed = 10,
	radius = 48*FRACUNIT,
	height = 160*FRACUNIT,
	dispoffset = 0,
	mass = 100,
	damage = 0,
	activesound = sfx_None,
	flags = MF_SHOOTABLE|MF_NOGRAVITY|MF_ENEMY|MF_SPECIAL,
	raisestate = S_NULL
}

mobjinfo[MT_FAKEBRAK].rfwpainchance = 0
mobjinfo[MT_FAKEBRAK].sparktype = MT_SMOKE
mobjinfo[MT_FAKEBRAK].bloodtype = MT_NULL
mobjinfo[MT_FAKEBRAK].rfwdamage = 0
mobjinfo[MT_FAKEBRAK].rfwmaxdamage = 0

states[S_GLUP_SHITTO] = {
	sprite = SPR_BRAK,
	frame = A|FF_FULLBRIGHT,
	//tics = 805,
	tics = -1,
	nextstate = S_NULL
}

freeslot("MT_FAKEROCKET")
freeslot("S_GLUP_ROCKET")

mobjinfo[MT_FAKEROCKET] = {
	//$Category "Rampage Scripting"
	doomednum = -1,
	spawnstate = S_GLUP_ROCKET,
	spawnhealth = 999999999,
	seestate = S_NULL,
	seesound = sfx_null,
	reactiontime = 1,
	attacksound = sfx_null,
	painstate = S_NULL,
	painchance = 8192,
	painsound = sfx_null,
	meleestate = S_NULL,
	missilestate = S_NULL,
	deathstate = S_NULL,
	xdeathstate = S_NULL,
	deathsound = sfx_wpnup,
	speed = 40*FRACUNIT,
	radius = 11*FRACUNIT,
	height = 8*FRACUNIT,
	dispoffset = 0,
	mass = 100,
	damage = 0,
	activesound = sfx_None,
	flags = MF_MISSILE|MF_SPECIAL|MF_NOBLOCKMAP|MF_NOGRAVITY,
	raisestate = S_NULL
}

//mobjinfo[MT_FAKEROCKET].rfwdamage = 0
//mobjinfo[MT_FAKEROCKET].rfwmaxdamage = 0

RFW.DAMAGETABLE[MT_FAKEROCKET] = {0, 0}

states[S_GLUP_ROCKET] = {
	sprite = SPR_RMPR,
	frame = A|FF_FULLBRIGHT,
	tics = -1,
	nextstate = S_GLUP_ROCKET
}

local brakmovetable = { //tic, x, y, z, angle
	{0, 1856*FU, 7488*FU, 232*FU, ANGLE_90},
	{1, 1856*FU, 7504*FU, 160*FU, ANGLE_90},
	{2, 1856*FU, 7536*FU, 96*FU, ANGLE_90},
	{3, 1856*FU, 7584*FU, 48*FU, ANGLE_90},
	{4, 1856*FU, 7648*FU, 32*FU, ANGLE_90},
	{35, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{40, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{45, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{50, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{55, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{60, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{65, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{70, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{75, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{80, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{85, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{90, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{95, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{100, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{105, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{110, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{115, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{120, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{125, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{130, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{135, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{140, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{145, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{150, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{155, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{160, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{165, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{170, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{175, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{180, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{185, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{190, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{195, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{200, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{205, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{210, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{215, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{220, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{225, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{230, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{235, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{240, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{245, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{250, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{255, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{260, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{265, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{270, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{275, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{280, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{285, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{290, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{295, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{300, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{305, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{310, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{315, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{320, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{325, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{330, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{335, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{340, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{345, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{350, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{355, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{360, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{365, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{370, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{375, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{380, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{385, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{390, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{395, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{400, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{405, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{410, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{415, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{420, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{425, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{430, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{435, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{440, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{445, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{450, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{455, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{460, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{465, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{470, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{475, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{480, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{485, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{490, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{495, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{500, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{505, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{510, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{515, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{520, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{525, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{530, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{535, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{540, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{545, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{550, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{555, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{560, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{565, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{570, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{575, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{580, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{585, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{590, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{595, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{600, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{605, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{610, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{615, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{620, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{625, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{630, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{635, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{640, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{645, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{650, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{655, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{660, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{665, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{670, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{675, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{680, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{685, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{690, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{695, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{700, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{705, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{710, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{715, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{720, 1872*FU, 8704*FU, 20*FU, ANGLE_90},
	{725, 1880*FU, 8704*FU, 24*FU, ANGLE_90},
	{730, 1872*FU, 8704*FU, 28*FU, ANGLE_90},
	{735, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{740, 1840*FU, 8704*FU, 20*FU, ANGLE_90},
	{745, 1832*FU, 8704*FU, 24*FU, ANGLE_90},
	{750, 1840*FU, 8704*FU, 28*FU, ANGLE_90},
	{755, 1856*FU, 8704*FU, 24*FU, ANGLE_90},
	{760, 1856*FU, 8704*FU, 24*FU, ANGLE_45},
	{765, 1856*FU, 8704*FU, 24*FU, 0},
	{770, 1856*FU, 8704*FU, 24*FU, ANG1*-20},
	{800, 2410*FU, 8503*FU, 32*FU, ANG1*-20},
	{801, 2470*FU, 8481*FU, 48*FU, ANG1*-20},
	{802, 2515*FU, 8464*FU, 96*FU, ANG1*-20},
	{803, 2545*FU, 8453*FU, 160*FU, ANG1*-20},
	{804, 2560*FU, 8448*FU, 232*FU, 0},
	{805, 2560*FU, 8448*FU, 232*FU, 0}
}

addHook("MobjThinker", function(mo)
	if mo.brak_animtimer == nil then
		mo.brak_animtimer = 0
	end
	mo.frame = 13|FF_FULLBRIGHT
	local ourframe
	for i = 1,#brakmovetable do
		if mo.brak_animtimer >= brakmovetable[i][1] then
			ourframe = i
			continue //no break because everything before our actual 
		else
			break //no more past this should be greater than or equal so break here
		end
	end
	if mo.brak_animtimer == 805 then
		P_RemoveMobj(mo)
		return
	end
	if ourframe == 6 or ourframe == 150 then
		mo.frame = 10|FF_FULLBRIGHT
	elseif ourframe == 7 or ourframe == 149 then
		mo.frame = 7|FF_FULLBRIGHT
	end
	if ourframe >= 8 and ourframe < 149 then
		mo.frame = 11|FF_FULLBRIGHT
	end
	if ourframe >= 10 and ourframe <= 75 then
		for p in players.iterate do
			local angle = R_PointToAngle2(mo.x, mo.y, p.mo.x, p.mo.y)
			local dx = mo.x - (p.mo.x)
			local dy = mo.y - (p.mo.y)
			local dz = mo.z+mo.height*3/4 - (p.mo.z+p.mo.height/2)
			local dxy = P_AproxDistance(dx, dy)
			local aim = -R_PointToAngle2(0, 0, dxy, dz)
			S_StartSound(mo, sfx_chaing)
			for i = 1, 3 do
				local s1 = FixedAngle(P_RandomRange(-15*FU, 15*FU))
				local s2 = FixedAngle(P_RandomRange(-5*FU*3/2, 5*FU*3/2)) //32*FU, 32*FU, 136*FU
				local targetlist = P_AngleRaycast{x = mo.x+32*FU, y = mo.y+32*FU, z = mo.z+136*FU, ang = angle + s1, zang = aim + s2, distance = 4096*FU, steps = 256, tclip = true, lclip = true, ignore = mo, callback = P_SpawnMobj, callback2 = P_SpawnMobj, arg = MT_TRACER, larg = MT_SMOKE}
				if not next(targetlist) then continue end
				local target = targetlist[1][4]
				P_Thrust(target, angle+s1, 15*FU) //slam the player back
				if target.player.phealth <= 50 then return end //don't heal the player if they have under 50 health obviously
				target.player.phealth = max($ - P_RandomRange(3, 5), 50) //damage the player but only down to 50 health so they can't actually die
			end
		end
	end
	if mo.brak_animtimer == 405 then
		S_StartSound(mo, sfx_beragh)
		//A_VileTarget(mo, MT_CYBRAKDEMON_TARGET_RETICULE, 1)
	end
	if mo.brak_animtimer == 440 then //1 second after the "RAGHHHH"
		S_StartSound(mo, sfx_trpowr)
	end
	if mo.brak_animtimer == 545 then //3 seconds after the charge sound
		S_StartSound(mo, sfx_cannon)
		for p in players.iterate do
			//MT_FAKEROCKET
			local rock = P_SpawnMobjFromMobj(mo, 32*FU, 32*FU, 136*FU, MT_FAKEROCKET)
			rock.target = mo
			rock.tracer = p.mo
			rock.angle = mo.angle
			local speed = rock.info.speed
			rock.momx = FixedMul(speed, cos(rock.angle))
			rock.momy = FixedMul(speed, sin(rock.angle))
			rock.rfwdamage = 0
		end
	end
	if ourframe ~= nil then
		local curr = mo.brak_animtimer*FU
		local mini = brakmovetable[ourframe][1]*FU
		local maxi = brakmovetable[ourframe+1][1]*FU 
		local interppercent = FixedDiv((curr-mini),(maxi-mini))
		mini = brakmovetable[ourframe]
		maxi = brakmovetable[ourframe+1]
		P_MoveOrigin(mo, ease.linear(interppercent, mini[2], maxi[2]), ease.linear(interppercent, mini[3], maxi[3]), ease.linear(interppercent, mini[4], maxi[4]))
		mo.angle = mini[5]
	end
	for p in players.iterate do
		if p.mo.y <= 8704*FU then
			P_InstaThrust(p.mo, ANGLE_90, 32*FU)
		end
	end
	for p in players.iterate do
		if p.mo.brak_bloodscreen then
			p.mo.angle = R_PointToAngle2(p.mo.x, p.mo.y, mo.x, mo.y)
			local dx = p.mo.x - mo.x
			local dy = p.mo.y - mo.y
			local dz = p.mo.z - (mo.z+mo.height/2)
			local dxy = P_AproxDistance(dx, dy)
			p.aiming = -R_PointToAngle2(0, 0, dxy, dz)
		end
	end
	//wings
	local ang = mo.angle
	for i = 64, 160, 32 do
		for j = -1, 1, 2 do
			local offx = mo.x - 32*cos(ang) - j*i*cos(ang+ANGLE_90)
			local offy = mo.y - 32*sin(ang) - j*i*sin(ang+ANGLE_90)
			local ghost = P_SpawnGhostMobj(mo)
			if not ghost then continue end
			ghost.sprite = SPR_THOK
			ghost.frame = 1
			ghost.scale = FU/4
			ghost.blendmode = AST_ADD
			ghost.renderflags = $|RF_FULLBRIGHT
			P_SetObjectMomZ(ghost, -(192-i)*FU/2, true)
			P_SetOrigin(ghost, offx, offy, mo.z+mo.height)
		end
	end
	mo.brak_animtimer = $+1
end, MT_FAKEBRAK)

addHook("MobjThinker", function(mo)
	if mo.tracer == nil then return end
	local p = mo.tracer.player
	local angle = R_PointToAngle2(mo.x, mo.y, p.mo.x, p.mo.y)
	local dx = mo.x - (p.mo.x)
	local dy = mo.y - (p.mo.y)
	local dz = mo.z+mo.height/2 - (p.mo.z+p.mo.height/2)
	local dxy = P_AproxDistance(dx, dy)
	local aim = -R_PointToAngle2(0, 0, dxy, dz)
	local speed = mo.info.speed
	mo.momx = FixedMul(FixedMul(speed, cos(angle)),cos(aim))
	mo.momy = FixedMul(FixedMul(speed, sin(angle)),cos(aim))
	mo.momz = FixedMul(speed, sin(aim))
	mo.angle = angle
end, MT_FAKEROCKET)

addHook("MobjRemoved", function(mo)
	if mo.tracer == nil then return end
	S_StartSound(mo, sfx_s3k4e)
	local p = mo.tracer.player
	S_StartSound(p.mo, sfx_GIB1)
	S_StartSound(p.mo, sfx_GIB2)
	p.weaponslist = {
		[1] = {},
		[2] = {},
		[3] = {},
		[4] = {},
		[5] = {},
		[6] = {},
		[7] = {},
		[8] = {},
		[9] = {},
		[10] = {},
	}
	RFW.GivePlayerWeapon(p, 1, RFW.WP_knife)
	RFW.GivePlayerWeapon(p, 2, RFW.WP_pistol)
	p.weaponstate = "Raise"
	p.raiselowercounter = 32
	p.weaponframe = 1
	p.weapon = RFW.WP_pistol
	p.slot = 2
	p.phealth = 1
	p.mo.pstun = 280
	p.mo.brak_bloodscreen = 280
	P_InstaThrust(p.mo, ANGLE_90, 64*FU)
	P_SetObjectMomZ(p.mo, 16*FU, false)
end, MT_FAKEROCKET)

addHook("PlayerThink", function(p)
	if not (p.mo and p.mo.valid) then return end
	if p.mo.pstun == nil then
		p.mo.pstun = 0
	end
	if p.mo.brak_bloodscreen == nil then
		p.mo.brak_bloodscreen = 0
	end
	if p.mo.pstun >= 1 then
		p.pflags = $|PF_FULLSTASIS
		p.mo.pstun = max($-1, 0)
		if p.mo.pstun == 0 then
			p.pflags = $ & ~PF_FULLSTASIS
		end
	end
	if p.mo.brak_bloodscreen >= 1 then
		p.mo.brak_bloodscreen = max($-1, 0)
		p.viewheight = -36*FU
		p.weaponstate = "Raise"
		p.raiselowercounter = 32
	end
end)

hud.add(function(v, p, c)
	if not p.mo.brak_bloodscreen then return end
	local alpha = 0
	local bloody = max(p.mo.brak_bloodscreen-140, 0)
	if bloody == 9 then
		alpha = V_10TRANS
	elseif bloody == 8 then
		alpha = V_20TRANS
	elseif bloody == 7 then
		alpha = V_30TRANS
	elseif bloody == 6 then
		alpha = V_40TRANS
	elseif bloody == 5 then
		alpha = V_50TRANS
	elseif bloody == 4 then
		alpha = V_60TRANS
	elseif bloody == 3 then
		alpha = V_70TRANS
	elseif bloody == 2 then
		alpha = V_80TRANS
	elseif bloody == 1 then
		alpha = V_90TRANS
	end
	if bloody then
		v.drawFill(0, 0, 999, splitscreen and v.height()/3 or v.height(), 35|V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|alpha)
	end
	//local bloody2 = p.mo.brak_bloodscreen
	//local view = -36*FU
end, "game")